home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / board / AmiGo.lha / AmiGo / goplayutils.c < prev    next >
C/C++ Source or Header  |  1989-12-12  |  37KB  |  1,340 lines

  1. /* The go player utilities */
  2. /* Ported from Pascal to C by Todd R. Johnson */
  3. /* From the original Pascal file:
  4. Copyright (c) 1983 by Three Rivers Computer Corp.
  5.  
  6. Written: January 17, 1983 by Stoney Ballard
  7. */
  8.  
  9. #include "goplayutils.h"
  10. #include "go.h"
  11.  
  12. extern struct bRec goboard[19][19];
  13. extern removestone( short, short );
  14. extern placestone( enum bVal, short, short );
  15.  
  16. intBoard  claim, extra, bord, ndbord, sGroups, threatBord,
  17.           groupIDs, connectMap, protPoints;
  18. boolBoard  groupSeen, legal;
  19. short maxGroupID;
  20. pointList pList, pList1, plist2, plist3, pPlist;
  21. intList nlcGroup, aList;
  22. sgRec sList[401];
  23. groupRec gList[maxGroup];
  24. short killFlag,
  25.       numCapt,
  26.       utilPlayLevel,
  27.       treeLibLim;
  28. sType mySType;
  29. short showTrees;
  30. short sGlist[maxGroup+1];
  31. short depthLimit;
  32. intBoard markBoard;
  33. short marker;
  34.  
  35. short saveable(short, short, short *, short *);
  36. extern short killable(short, short, short *, short *);
  37. initBoolBoard(boolBoard);
  38. spanGroup(short, short, pointList *);
  39. sSpanGroup( short, short, sPointList *);
  40. intersectPlist(pointList *, pointList *, pointList *);
  41. initArray(intBoard);
  42. initState();
  43. copyArray(intBoard, intBoard);
  44. stake();
  45. spread();
  46. respreicen();
  47. tryPlay(short, short, short);
  48. genState();
  49. saveState();
  50. restoreState();
  51. short tencen(short, short);
  52. genConnects();
  53. initGPUtils();
  54. sortLibs();
  55.  
  56. short adjInAtari, adj2Libs,
  57.   intersectNum, spanNum, libMark;
  58. playRec playStack[1025];
  59. short playMark,
  60.   newGID,
  61.   tryLevel,
  62.   grpMark,
  63.   gMap[maxGroup];
  64. short dbStop, inGenState;
  65.  
  66.  pause()
  67. { /* pause */
  68. /*  if (dbStop and ! inGenState)
  69.     {
  70.       while ! tabswitch do;
  71.       repeat
  72.         if (tabYellow)
  73.           dbStop = false;
  74.       until ! tabswitch;
  75.     }     */
  76. } /* pause */
  77.  
  78. sstone(w, x, y, numb)
  79. short w, x, y, numb;
  80. { /* sstone */
  81.   if (w == 1)
  82.     placestone(mySType, x, y);
  83.   else if (mySType == WHITE)
  84.     placestone(BLACK, x, y);
  85.   else
  86.     placestone(WHITE, x, y);
  87. } /* sstone */
  88.  
  89. rstone(x, y)
  90. short x, y;
  91. { /* rstone */
  92.   removestone(x, y);
  93. } /* rstone */
  94.  
  95. initBoolBoard(bb)
  96. boolBoard bb;
  97. { /* initBoolBoard */
  98.   short i, j;
  99. #ifdef DEBUG
  100.   printf( "initBoolBoard\n" );
  101. #endif
  102.   for (i = 0; i <= maxPoint; i++)
  103.     for (j = 0; j <= maxPoint; j++)
  104.       bb[i][j] = FALSE;
  105. } /* initBoolBoard */
  106.  
  107. sortLibs()
  108. { /* sortLibs */
  109.   short i, j, t;
  110. #ifdef DEBUG
  111.   printf( "sortLibs\n" );
  112. #endif
  113.   for (i = 1; i <= maxGroupID; i++)
  114.     sGlist[i] = i;
  115.   for (i = 1; i < maxGroupID; i++)
  116.     for (j = i + 1; j <= maxGroupID; j++)
  117.       if (gList[sGlist[i]].libC > gList[sGlist[j]].libC)
  118.         {
  119.           t = sGlist[i];
  120.           sGlist[i] = sGlist[j];
  121.           sGlist[j] = t;
  122.         }
  123. } /* sortLibs */
  124.  
  125. spanGroupspan(x, y, libs, lookFor)
  126. short x, y, lookFor;
  127. pointList *libs;
  128.   { /* span */
  129.     markBoard[x][y] = marker;
  130.     if (bord[x][y] == 0)
  131.       {
  132.         libs->indx = libs->indx + 1;
  133.         libs->p[libs->indx].px = x;
  134.         libs->p[libs->indx].py = y;
  135.       }
  136.     else if (bord[x][y] == lookFor)
  137.       {
  138.         groupSeen[x][y] = TRUE;
  139.         if ((x > 0) && (markBoard[x - 1][y] != marker))
  140.           spanGroupspan(x - 1, y, libs, lookFor);
  141.         if ((y > 0) && (markBoard[x][y - 1] != marker))
  142.           spanGroupspan(x, y - 1, libs, lookFor);
  143.         if ((x < maxPoint) && (markBoard[x + 1][y] != marker))
  144.           spanGroupspan(x + 1, y, libs, lookFor);
  145.         if ((y < maxPoint) && (markBoard[x][y + 1] != marker))
  146.           spanGroupspan(x, y + 1, libs, lookFor);
  147.       }
  148.     else if (gList[gMap[groupIDs[x][y]]].libC == 1)
  149.       adjInAtari = TRUE;
  150.     else if ((gList[gMap[groupIDs[x][y]]].libC == 2) &&
  151.             (! gList[gMap[groupIDs[x][y]]].isLive))
  152.       adj2Libs = TRUE; 
  153.   } /* span */
  154.  
  155. spanGroup(x, y, libs)
  156. short x, y;
  157. pointList *libs;
  158. { /* spanGroup */
  159.   short lookFor;
  160. #ifdef DEBUG
  161.   printf( "spanGroup\n" );
  162. #endif
  163.   marker = marker + 1;
  164.   if (marker == 0)
  165.     {
  166.       initArray(markBoard);
  167.       marker = 1;
  168.     }
  169.   adjInAtari = FALSE;
  170.   adj2Libs = FALSE;
  171.   lookFor = bord[x][y];
  172.   libs->indx = 0;
  173.   spanGroupspan(x, y, libs, lookFor);
  174. } /* spanGroup */
  175.  
  176. sSpanGroupspan(x, y, libs, lookFor)
  177. short x, y, lookFor;
  178. sPointList *libs;
  179.   { /* span */
  180.     markBoard[x][y] = marker;
  181.     if (bord[x][y] == 0)
  182.       {
  183.         libs->indx += 1;
  184.         if (libs->indx <= maxSPoint)
  185.           {
  186.             libs->p[libs->indx].px = x;
  187.             libs->p[libs->indx].py = y;
  188.           }
  189.       }
  190.     else if (bord[x][y] == lookFor)
  191.       {
  192.         groupSeen[x][y] = TRUE;
  193.         if ((x > 0) && (markBoard[x - 1][y] != marker))
  194.           sSpanGroupspan(x - 1, y, libs, lookFor);
  195.         if ((y > 0) && (markBoard[x][y - 1] != marker))
  196.           sSpanGroupspan(x, y - 1, libs, lookFor);
  197.         if ((x < maxPoint) && (markBoard[x + 1][y] != marker))
  198.           sSpanGroupspan(x + 1, y, libs, lookFor);
  199.         if ((y < maxPoint) && (markBoard[x][y + 1] != marker))
  200.           sSpanGroupspan(x, y + 1, libs, lookFor);
  201.       }
  202.     else if (gList[gMap[groupIDs[x][y]]].libC == 1)
  203.       adjInAtari = TRUE;
  204.     else if ((gList[gMap[groupIDs[x][y]]].libC == 2) &&
  205.             (! gList[gMap[groupIDs[x][y]]].isLive)) 
  206.       adj2Libs = TRUE; 
  207.   } /* span */
  208.  
  209. sSpanGroup(x, y, libs)
  210. short x, y;
  211. sPointList *libs;
  212. { /* sSpanGroup */
  213.   short lookFor;
  214. #ifdef DEBUG
  215.   printf( "sSpanGroup\n" );
  216. #endif
  217.   marker = marker + 1;
  218.   if (marker == 0)
  219.     {
  220.       initArray(markBoard);
  221.       marker = 1;
  222.     }
  223.   adjInAtari = FALSE;
  224.   adj2Libs = FALSE;
  225.   lookFor = bord[x][y];
  226.   libs->indx = 0;
  227.   sSpanGroupspan(x, y, libs, lookFor);
  228. } /* sSpanGroup */
  229.  
  230. LAspan(x, y, me, him, iL)
  231. short x, y, me, him;
  232. intList *iL;
  233.   { /* span */
  234. #ifdef DEBUG
  235.   printf( "LAspan\n" );
  236. #endif
  237.     markBoard[x][y] = marker;
  238.     if (bord[x][y] == me)
  239.       {
  240.         if ((x > 0) && (markBoard[x - 1][y] != marker))
  241.           LAspan(x - 1, y, me, him, iL);
  242.         if ((x < maxPoint) && (markBoard[x + 1][y] != marker))
  243.           LAspan(x + 1, y, me, him, iL);
  244.         if ((y > 0) && (markBoard[x][y - 1] != marker))
  245.           LAspan(x, y - 1, me, him, iL);
  246.         if ((y < maxPoint) && (markBoard[x][y + 1] != marker))
  247.           LAspan(x, y + 1, me, him, iL);
  248.       }
  249.     else if (bord[x][y] == him)
  250.       if (gList[gMap[groupIDs[x][y]]].groupMark != grpMark)
  251.         {
  252.           gList[gMap[groupIDs[x][y]]].groupMark = grpMark;
  253.           iL->indx = iL->indx + 1;
  254.           iL->v[iL->indx] = gMap[groupIDs[x][y]];
  255.         }
  256.   } /* span */
  257.  
  258. listAdjacents(x, y, iL)
  259. short x, y;
  260. intList *iL;
  261. { /* listAdjacents */
  262.   short me, him;
  263. #ifdef DEBUG
  264.   printf( "listAdjacents\n" );
  265. #endif
  266.   grpMark = grpMark + 1;
  267.   marker = marker + 1;
  268.   if (marker == 0)
  269.     {
  270.       initArray(markBoard);
  271.       marker = 1;
  272.     }
  273.   iL->indx = 0;
  274.   me = bord[x][y];
  275.   him = -me;
  276.   LAspan(x, y, me , him, iL);
  277. } /* listAdjacents */
  278.  
  279. LDspan(x, y, me, diags)
  280. short x, y, me;
  281. sPointList *diags;
  282.   { /* span */
  283. #ifdef DEBUG
  284.   printf( "LDspan\n" );
  285. #endif
  286.     markBoard[x][y] = marker;
  287.     if ((x > 0) && (y > 0) &&
  288.        (bord[x - 1][y - 1] == 0) &&
  289.        (bord[x][y - 1] != me) &&
  290.        (bord[x - 1][y] != me) &&
  291.        (markBoard[x - 1][y - 1] != marker))
  292.       {
  293.         markBoard[x - 1][y - 1] = marker;
  294.         diags->indx = diags->indx + 1;
  295.         if (diags->indx <= maxSPoint)
  296.             {
  297.               diags->p[diags->indx].px = x - 1;
  298.               diags->p[diags->indx].py = y - 1;
  299.             }
  300.       }
  301.     if ((x < maxPoint) && (y > 0) &&
  302.        (bord[x + 1][y - 1] == 0) &&
  303.        (bord[x][y - 1] != me) &&
  304.        (bord[x + 1][y] != me) &&
  305.        (markBoard[x + 1][y - 1] != marker))
  306.       {
  307.         markBoard[x + 1][y - 1] = marker;
  308.         diags->indx = diags->indx + 1;
  309.         if (diags->indx <= maxSPoint)
  310.        {
  311.               diags->p[diags->indx].px = x + 1;
  312.               diags->p[diags->indx].py = y - 1;
  313.            }
  314.       }
  315.     if ((x > 0) && (y < maxPoint) &&
  316.        (bord[x - 1][y + 1] == 0) &&
  317.        (bord[x][y + 1] != me) &&
  318.        (bord[x - 1][y] != me) &&
  319.        (markBoard[x - 1][y + 1] != marker))
  320.       {
  321.         markBoard[x - 1][y + 1] = marker;
  322.         diags->indx = diags->indx + 1;
  323.         if (diags->indx <= maxSPoint)
  324.             {
  325.               diags->p[diags->indx].px = x - 1;
  326.               diags->p[diags->indx].py = y + 1;
  327.             }
  328.       }
  329.     if ((x < maxPoint) && (y < maxPoint) &&
  330.        (bord[x + 1][y + 1] == 0) &&
  331.        (bord[x][y + 1] != me) &&
  332.        (bord[x + 1][y] != me) &&
  333.        (markBoard[x + 1][y + 1] != marker))
  334.       {
  335.         markBoard[x + 1][y + 1] = marker;
  336.         diags->indx = diags->indx + 1;
  337.         if (diags->indx <= maxSPoint)
  338.             {
  339.               diags->p[diags->indx].px = x + 1;
  340.               diags->p[diags->indx].py = y + 1;
  341.             }
  342.       }
  343.     if ((x > 0) && (bord[x - 1][y] == me) &&
  344.        (markBoard[x - 1][y] != marker))
  345.       LDspan(x - 1, y, me, diags);
  346.     if ((x < maxPoint) && (bord[x + 1][y] == me) &&
  347.        (markBoard[x + 1][y] != marker))
  348.       LDspan(x + 1, y, me, diags);
  349.     if ((y > 0) && (bord[x][y - 1] == me) &&
  350.        (markBoard[x][y - 1] != marker))
  351.       LDspan(x, y - 1, me, diags);
  352.     if ((y < maxPoint) && (bord[x][y + 1] == me) &&
  353.        (markBoard[x][y + 1] != marker))
  354.       LDspan(x, y + 1, me , diags);
  355. } /* span */
  356.  
  357. listDiags(x, y, diags)
  358. short x, y;
  359. sPointList *diags;
  360. { /* listDiags */
  361.   short me;
  362. #ifdef DEBUG
  363.   printf( "listDiags\n" );
  364. #endif
  365.   me = bord[x][y];
  366.   diags->indx = 0;
  367.   marker = marker + 1;
  368.   if (marker == 0)
  369.     {
  370.       initArray(markBoard);
  371.       marker = 1;
  372.     }
  373.   LDspan(x, y, me, diags);
  374. } /* listDiags */
  375.  
  376. intersectPlist(p1, p2, pr)
  377. pointList *p1, *p2, *pr;
  378. { /* intersectPlist */
  379.   short i, j, k;
  380. #ifdef DEBUG
  381.   printf( "intersectPlist\n" );
  382. #endif
  383.   marker = marker + 1;
  384.   if (marker == 0)
  385.     {
  386.       initArray(markBoard);
  387.       marker = 1;
  388.     }
  389.   pr->indx = 0;
  390.   for (i = 1; i <= p1->indx; i++)
  391.       markBoard[p1->p[i].px][p1->p[i].py] = marker;
  392.   j = 0;
  393.   for (i = 1; i <= p2->indx; i++)
  394.       if (markBoard[p2->p[i].px][p2->p[i].py] == marker)
  395.         {
  396.           j = j + 1;
  397.           pr->p[j] = p2->p[i];
  398.         }
  399.   pr->indx = j;
  400. } /* intersectPlist */
  401.  
  402. initArray(ary)
  403. intBoard ary;
  404. { /* initArray */
  405.   short i, j;
  406.   for (i = 0; i <= maxPoint; i++)
  407.     for (j = 0; j <= maxPoint; j++)
  408.       ary[i][j] = 0;
  409. } /* initArray */
  410.  
  411. initState()
  412. { /* initState */
  413.   short i, j;
  414.   for (i = 0; i <= maxPoint; i++)
  415.     for (j = 0; j <=  maxPoint; j++)
  416.       {
  417.         extra[i][j] = 0;
  418.         claim[i][j] = 0;
  419.         groupIDs[i][j] = 0;
  420.         connectMap[i][j] = 0;
  421.         protPoints[i][j] = 0;
  422.       }
  423. } /* initState */
  424.  
  425. copyArray( dest, src )
  426. intBoard dest, src;
  427. {
  428.    short x, y;
  429.    for (y = 0; y <= maxPoint; y++)
  430.       for (x = 0; x <= maxPoint; x++)
  431.          dest[x][y] = src[x][y];
  432. }
  433.  
  434. /*
  435.   generates a one-point spread in the force field array (claim)
  436.  
  437.   the spread from a single point after four calls is:
  438.  
  439.               1
  440.            2  2  2
  441.         2  4  6  4  2
  442.      2  4  8 10  8  4  2
  443.   1  2  6 10 62 10  6  2  1  
  444.      2  4  8 10  8  4  2
  445.         2  4  6  4  2
  446.            2  2  2
  447.               1
  448.  
  449. */
  450. stake()
  451. {
  452.    short x, y;
  453.    initArray( extra );
  454.    for (y = 0; y <= maxPoint; y++)
  455.       for (x = 0; x <= maxPoint; x++)
  456.       {
  457.          extra[x][y] = extra[x][y] + claim[x][y];
  458.      if (claim[x][y] > 0)
  459.      {
  460.         if (x > 0) extra[x-1][y] += 1;
  461.         if (y > 0) extra[x][y-1] += 1;
  462.         if (x < maxPoint) extra[x+1][y] += 1;
  463.         if (y < maxPoint) extra[x][y+1] += 1;
  464.      }
  465.          else if (claim[x][y] < 0)
  466.      {
  467.         if (x > 0) extra[x-1][y] -= 1;
  468.         if (y > 0) extra[x][y-1] -= 1;
  469.         if (x < maxPoint) extra[x+1][y] -= 1;
  470.         if (y < maxPoint) extra[x][y+1] -= 1;
  471.      }
  472.       }
  473.    copyArray( claim, extra );
  474. } /* stake */
  475.  
  476. /*
  477.   sets up claim from the current board position
  478. */
  479. spread()
  480. {
  481.    short x, y;
  482.    for (y = 0; y <= maxPoint; y++)
  483.       for (x = 0; x <= maxPoint; x++)
  484.          claim[x][y] = ndbord[x][y] * 50;
  485.    stake();
  486.    stake();
  487.    stake();
  488.    stake();
  489. } /* spread */
  490.  
  491. /*
  492.   gList is initialized with the size, loc, and libCount of each group
  493.   groupIDs contains the serial numbers of the groups.
  494. */
  495. Resspan(x, y, gID, gSize, libCount, who)
  496. short x, y, gID, *gSize, *libCount, who;
  497.   { /* span */
  498.     if ((bord[x][y] == 0) &&
  499.        (markBoard[x][y] != marker)) /* a liberty */
  500.       {
  501.         markBoard[x][y] = marker;
  502.         *libCount = *libCount + 1;
  503.       }
  504.     else if ((bord[x][y] == who) &&
  505.             (groupIDs[x][y] == 0))
  506.       {
  507.         groupIDs[x][y] = gID;
  508.         *gSize = *gSize + 1;
  509.         if (x > 0)
  510.           Resspan(x - 1, y, gID, gSize, libCount, who);
  511.         if (x < maxPoint)
  512.           Resspan(x + 1, y, gID, gSize, libCount, who);
  513.         if (y > 0)
  514.           Resspan(x, y - 1, gID, gSize, libCount, who);
  515.         if (y < maxPoint)
  516.           Resspan(x, y + 1, gID, gSize, libCount, who);
  517.       }
  518.   } /* span */
  519.  
  520. respreicen()
  521. { /* respreicen */
  522.   short i, j, gID, libCount, gSize, who;
  523.   gID = 0;
  524. #ifdef DEBUG
  525.   printf( "respreicen\n" );
  526. #endif
  527.   for (i = 0; i <= maxPoint; i++)
  528.     for (j = 0; j <= maxPoint; j++)
  529.       groupIDs[i][j] = 0;
  530.   for (i = 0; i <= maxPoint; i++)
  531.     for (j = 0; j <= maxPoint; j++)
  532.       if ((bord[i][j] != 0) &&   /* a stone there */
  533.          (groupIDs[i][j] == 0)) /* not seen yet */
  534.         {
  535.           marker = marker + 1;
  536.           if (marker == 0)
  537.             {
  538.               initArray(markBoard);
  539.               marker = 1;
  540.             }
  541.           gID = gID + 1;
  542.           libCount = 0;
  543.           gSize = 0;
  544.           who = bord[i][j];
  545.           Resspan(i, j, gID, &gSize, &libCount, who); /* span the group, collecting info */
  546.               gList[gID].groupMark = 0;
  547.               gList[gID].atLevel = 0;
  548.               gList[gID].isLive = FALSE; /* we don't know yet */
  549.               gList[gID].isDead = FALSE;
  550.               gList[gID].numEyes = -1;
  551.               gList[gID].size = gSize;
  552.               gList[gID].libC = libCount;
  553.               gList[gID].lx = i;
  554.               gList[gID].ly = j;
  555.           gMap[gID] = gID; /* set up identity map */
  556.         }
  557.   maxGroupID = gID;
  558.   newGID = gID;
  559.   grpMark = 0;
  560. } /* respreicen */
  561.  
  562. /*
  563.   play z at [x, y].
  564.   killFlag is set true if anything is killed.
  565. */
  566. killGroup(x, y, me, him)
  567. short x, y, me, him;
  568.   { /* killGroup */
  569. #ifdef DEBUG
  570.   printf( "killGroup\n" );
  571. #endif
  572.     playMark = playMark + 1;
  573.                 /* record this kill */
  574.         playStack[playMark].kind = rem;
  575.         playStack[playMark].uval.rem.who = him;
  576.         playStack[playMark].uval.rem.xl = x;
  577.         playStack[playMark].uval.rem.yl = y;
  578.         playStack[playMark].gID = groupIDs[x][y];
  579.         playStack[playMark].uval.rem.sNumber = goboard[x][y].mNum;
  580.         if (showTrees)
  581.           rstone(x, y);
  582.     numCapt = numCapt + 1;
  583.     bord[x][y] = 0;
  584.     groupIDs[x][y] = 0;
  585.     if (x > 0)
  586.       {
  587.         if (bord[x - 1][y] == me)
  588.           {
  589.             nlcGroup.indx = nlcGroup.indx + 1;
  590.             nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]];
  591.           }
  592.         else if (bord[x - 1][y] == him)
  593.           killGroup(x - 1, y, me , him);
  594.       }
  595.     if (x < maxPoint)
  596.       {
  597.         if (bord[x + 1][y] == me)
  598.           {
  599.             nlcGroup.indx = nlcGroup.indx + 1;
  600.             nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]];
  601.           }
  602.         else if (bord[x + 1][y] == him)
  603.           killGroup(x + 1, y, me, him);
  604.       }
  605.     if (y > 0)
  606.       {
  607.         if (bord[x][y - 1] == me)
  608.           {
  609.             nlcGroup.indx = nlcGroup.indx + 1;
  610.             nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]];
  611.           }
  612.         else if (bord[x][y - 1] == him)
  613.           killGroup(x, y - 1, me, him);
  614.       }
  615.     if (y < maxPoint)
  616.       {
  617.         if (bord[x][y + 1] == me)
  618.           {
  619.             nlcGroup.indx = nlcGroup.indx + 1;
  620.             nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]];
  621.           }
  622.         else if (bord[x][y + 1] == him)
  623.           killGroup(x, y + 1, me, him);
  624.       }
  625.   } /* killGroup */
  626.  
  627. mergeGroup(sGID, myGID)
  628. short sGID, myGID;
  629.   { /* mergeGroup */
  630.     short i;
  631. #ifdef DEBUG
  632.   printf( "mergeGroup\n" );
  633. #endif
  634.     for (i = 1; i <= newGID; i++)
  635.       if (gMap[i] == sGID)
  636.         {
  637.           playMark = playMark + 1;
  638.               playStack[playMark].kind = reMap;
  639.               playStack[playMark].gID = i;
  640.               playStack[playMark].uval.reMap.oldGID = sGID;
  641.           gMap[i] = myGID;
  642.         }
  643.   } /* mergeGroup */
  644.  
  645. tryPlay(x, y, z)
  646. short x, y, z;
  647. { /* plei */
  648.   short i, me, him, myGID;
  649.   short isNew;
  650. #ifdef DEBUG
  651.   printf( "tryPlay\n" );
  652. #endif
  653.   me = z;
  654.   him = -me;
  655.   killFlag = FALSE;  /* set true if something is killed */
  656.   numCapt = 0;
  657.   tryLevel = tryLevel + 1;
  658.   isNew = FALSE;
  659.   bord[x][y] = z;  /* play the stone */
  660.   if ((x > 0) && (bord[x - 1][y] == me))   /* connect to adjacent group */
  661.     myGID = gMap[groupIDs[x - 1][y]];
  662.   else if ((x < maxPoint) && (bord[x + 1][y] == me))
  663.     myGID = gMap[groupIDs[x + 1][y]];
  664.   else if ((y > 0) && (bord[x][y - 1] == me))
  665.     myGID = gMap[groupIDs[x][y - 1]];
  666.   else if ((y < maxPoint) && (bord[x][y + 1] == me))
  667.     myGID = gMap[groupIDs[x][y + 1]];
  668.   else  /* nobody to connect to */
  669.     {
  670.       newGID = newGID + 1;
  671.       isNew = TRUE;
  672.       myGID = newGID;
  673.           gList[myGID].groupMark = 0;
  674.           gList[myGID].atLevel = tryLevel;
  675.           gList[myGID].isLive = FALSE;
  676.           gList[myGID].numEyes = -1;
  677.           gList[myGID].size = -1;
  678.           gList[myGID].lx = x;
  679.           gList[myGID].ly = y;
  680.       gMap[myGID] = myGID;
  681.     }
  682.   groupIDs[x][y] = myGID;
  683.   playMark = playMark + 1;
  684.       /* record this move */
  685.       playStack[playMark].kind = add;
  686.       playStack[playMark].uval.add.who = me;
  687.       playStack[playMark].uval.add.xl = x;
  688.       playStack[playMark].uval.add.yl = y;
  689.       playStack[playMark].gID = myGID;
  690.       playStack[playMark].uval.add.sNumber = 0;
  691.       if (isNew)
  692.         playStack[playMark].uval.add.nextGID = newGID - 1;
  693.       else
  694.         playStack[playMark].uval.add.nextGID = newGID;
  695.       if (showTrees)
  696.         sstone(me, x, y, 0);
  697.   /* merge adjacent groups */
  698.   if ((x > 0) && (bord[x - 1][y] == me) &&
  699.      (gMap[groupIDs[x - 1][y]] != myGID))
  700.     mergeGroup(gMap[groupIDs[x - 1][y]], myGID);
  701.   if ((x < maxPoint) && (bord[x + 1][y] == me) &&
  702.      (gMap[groupIDs[x + 1][y]] != myGID))
  703.     mergeGroup(gMap[groupIDs[x + 1][y]], myGID);
  704.   if ((y > 0) && (bord[x][y - 1] == me) &&
  705.      (gMap[groupIDs[x][y - 1]] != myGID))
  706.     mergeGroup(gMap[groupIDs[x][y - 1]], myGID);
  707.   if ((y < maxPoint) && (bord[x][y + 1] == me) &&
  708.      (gMap[groupIDs[x][y + 1]] != myGID))
  709.     mergeGroup(gMap[groupIDs[x][y + 1]], myGID);
  710.   /* kill opposing groups, listing affected groups */
  711.   nlcGroup.indx = 1;
  712.   nlcGroup.v[1] = myGID; /* init list to include me */
  713.   if ((x > 0) && (bord[x - 1][y] == him) &&
  714.      (gList[gMap[groupIDs[x - 1][y]]].libC == 1))
  715.     {
  716.       killFlag = TRUE;
  717.       killGroup(x - 1, y, me, him);
  718.     }
  719.   if ((x < maxPoint) && (bord[x + 1][y] == him) &&
  720.      (gList[gMap[groupIDs[x + 1][y]]].libC == 1))
  721.     {
  722.       killFlag = TRUE;
  723.       killGroup(x + 1, y, me, him);
  724.     }
  725.   if ((y > 0) && (bord[x][y - 1] == him) &&
  726.      (gList[gMap[groupIDs[x][y - 1]]].libC == 1))
  727.     {
  728.       killFlag = TRUE;
  729.       killGroup(x, y - 1, me, him);
  730.     }
  731.   if ((y < maxPoint) && (bord[x][y + 1] == him) &&
  732.      (gList[gMap[groupIDs[x][y + 1]]].libC == 1))
  733.     {
  734.       killFlag = TRUE;
  735.       killGroup(x, y + 1, me, him);
  736.     }
  737.   /* list groups adjacent to me */
  738.   if ((x > 0) && (bord[x - 1][y] == him))
  739.     {
  740.       nlcGroup.indx = nlcGroup.indx + 1;
  741.       nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]];
  742.     }
  743.   if ((x < maxPoint) && (bord[x + 1][y] == him))
  744.     {
  745.       nlcGroup.indx = nlcGroup.indx + 1;
  746.       nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]];
  747.     }
  748.   if ((y > 0) && (bord[x][y - 1] == him))
  749.     {
  750.       nlcGroup.indx = nlcGroup.indx + 1;
  751.       nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]];
  752.     }
  753.   if ((y < maxPoint) && (bord[x][y + 1] == him))
  754.     {
  755.       nlcGroup.indx = nlcGroup.indx + 1;
  756.       nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]];
  757.     }
  758.   /* fix liberty count for affected groups */
  759.   grpMark = grpMark + 1;
  760.   for (i = 1; i <= nlcGroup.indx; i++)
  761.       if (gList[nlcGroup.v[i]].groupMark != grpMark)
  762.         {
  763.           if (gList[nlcGroup.v[i]].atLevel != tryLevel)
  764.             {
  765.               playMark = playMark + 1;
  766.                   playStack[playMark].kind = chLib;
  767.                   playStack[playMark].gID = nlcGroup.v[i];
  768.                   playStack[playMark].uval.chLib.oldLevel = 
  769.                        gList[nlcGroup.v[i]].atLevel;
  770.                   playStack[playMark].uval.chLib.oldLC =
  771.                        gList[nlcGroup.v[i]].libC;
  772.             }
  773.           gList[nlcGroup.v[i]].groupMark = grpMark;
  774.           gList[nlcGroup.v[i]].atLevel = tryLevel;
  775.           spanGroup(gList[nlcGroup.v[i]].lx, gList[nlcGroup.v[i]].ly, &pPlist);
  776.           gList[nlcGroup.v[i]].libC = pPlist.indx;
  777.         }
  778. } /* plei */
  779.  
  780. saveState()
  781. { /* saveState */
  782.   playMark = 0;
  783.   tryLevel = 0;
  784.   newGID = maxGroupID;
  785. } /* saveState */
  786.  
  787. /*
  788.   undoes a move sequence back to uMark
  789. */
  790. undoTo(uMark)
  791. short uMark;
  792. { /* undoTo */
  793.   short i, xl, yl;
  794. #ifdef DEBUG
  795.   printf( "undoTo\n" );
  796. #endif
  797.   for (i = playMark; i >= uMark + 1; i--)
  798.       if (playStack[i].kind == rem)
  799.         {
  800.           xl = playStack[i].uval.rem.xl;
  801.           yl = playStack[i].uval.rem.yl;
  802.           bord[xl][yl] = playStack[i].uval.rem.who;
  803.           groupIDs[xl][yl] = playStack[i].gID;
  804.           if (showTrees)
  805.             sstone(playStack[i].uval.rem.who, xl, yl,
  806.                playStack[i].uval.rem.sNumber);
  807.         }
  808.       else if (playStack[i].kind == add)
  809.         {
  810.           xl = playStack[i].uval.add.xl;
  811.           yl = playStack[i].uval.add.yl;
  812.           bord[xl][yl] = 0;
  813.           groupIDs[xl][yl] = 0;
  814.           tryLevel = tryLevel - 1;
  815.           newGID = playStack[i].uval.add.nextGID;
  816.           if (showTrees)
  817.             rstone(xl, yl);
  818.         }
  819.       else if (playStack[i].kind == reMap)
  820.         gMap[playStack[i].gID] = playStack[i].uval.reMap.oldGID;
  821.       else /* change libs of group - gID is pre-mapped */
  822.           {
  823.             gList[playStack[i].gID].libC = playStack[i].uval.chLib.oldLC;
  824.             gList[playStack[i].gID].atLevel = playStack[i].uval.chLib.oldLevel;
  825.           }
  826.   playMark = uMark;
  827. } /* undoTo */
  828.  
  829. /*
  830.   restores the state of the world after trying a move sequence
  831. */
  832. restoreState()
  833. { /* restoreState */
  834. #ifdef DEBUG
  835.   printf( "restoreState\n" );
  836. #endif
  837.   if (playMark > 0)
  838.     {
  839.       undoTo(0);
  840.       playMark = 0;
  841.       tryLevel = 0;
  842.     }
  843. } /* restoreState */
  844.  
  845. /* exception bpt; */
  846.  
  847.  
  848. /*
  849.   returns true if (the group (at gx, gy) is saveable.
  850.   if so, returns the point to play at in savex, savey
  851. */
  852. short saveable(gx, gy, savex, savey)
  853. short gx, gy, *savex, *savey;
  854. { /* saveable */
  855.   short me, him, gx1, gx2, i, j, smark, mark2, tl, result;
  856.   char sChar;
  857.   sPointList dList;
  858.   point tp;
  859.   short libList[maxSPoint+1];
  860. #ifdef DEBUG
  861.   printf( "saveable\n" );
  862. #endif
  863.   dbStop = TRUE;
  864.   me = bord[gx][gy];
  865.   him = -me;
  866.   if (me == 1)
  867.     sChar = '|';
  868.   else
  869.     sChar = '>';
  870. /*  write(sChar); */
  871.   spanGroup(gx, gy, &plist3); /* find my liberties */
  872.   if (adjInAtari) /* one of my options is to kill */
  873.     {
  874.       listAdjacents(gx, gy, &aList);
  875.       for (i = 1; i <= aList.indx; i++)
  876.         if (gList[aList.v[i]].libC == 1)
  877.             {
  878.               spanGroup(gList[aList.v[i]].lx, gList[aList.v[i]].ly,
  879.                  &pList1); /* find it's liberty */
  880.               plist3.indx = plist3.indx + 1;
  881.               plist3.p[plist3.indx].px = pList1.p[1].px;
  882.               plist3.p[plist3.indx].py = pList1.p[1].py;
  883.             }
  884.     }
  885.   for (i = 1; i <= maxSPoint; i++)
  886.     libList[i] = -1;
  887.   if ((utilPlayLevel > 4) &&
  888.      (gList[gMap[groupIDs[gx][gy]]].libC > 1)) /* account for diags */
  889.     {
  890.       listDiags(gx, gy, &dList);
  891.       j = 0;
  892.       i = plist3.indx;
  893.       while ((j < dList.indx) &&
  894.             (i < maxSPoint))
  895.         {
  896.           j = j + 1;
  897.           i = i + 1;
  898.           libList[i] = 100;
  899.               plist3.p[i].px = dList.p[j].px;
  900.               plist3.p[i].py = dList.p[j].py;
  901.         }
  902.       plist3.indx = i;
  903.     }
  904.   if (plist3.indx > 1) /* sort by decreasing lib count */
  905.     {
  906.       for (i = 1; i <= plist3.indx; i++)
  907.         if (libList[i] != 100)
  908.             {
  909.               mark2 = playMark;
  910.               tryPlay(plist3.p[i].px, plist3.p[i].py, me);
  911.               libList[i] = gList[gMap[groupIDs[gx][gy]]].libC;
  912.               if (libList[i] > treeLibLim) /* i'm safe */
  913.                 {
  914.                   *savex = plist3.p[i].px;
  915.                   *savey = plist3.p[i].py;
  916.                   result = TRUE;
  917.                   goto one;
  918.                 }
  919.               undoTo(mark2);
  920.             }
  921.       for (i = 1; i <= plist3.indx - 1; i++)
  922.         for (j = i + 1; j <= plist3.indx; j++)
  923.           if (libList[i] < libList[j])
  924.             {
  925.               tl = libList[i];
  926.               libList[i] = libList[j];
  927.               libList[j] = tl;
  928.               tp = plist3.p[i];
  929.               plist3.p[i] = plist3.p[j];
  930.               plist3.p[j] = tp;
  931.             }
  932.     }
  933.   for (i = 1; i <= plist3.indx; i++)
  934.     {
  935.       *savex = plist3.p[i].px;
  936.       *savey = plist3.p[i].py;
  937.       if (legal[*savex][*savey])
  938.         {
  939.           smark = playMark;
  940.           tryPlay(*savex, *savey, me);
  941.           pause();
  942.           if (gList[gMap[groupIDs[*savex][*savey]]].libC > 1)
  943.             if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim)
  944.               {
  945.                 restoreState();
  946. /*                sClearChar(sChar, rXor); */
  947.                 return TRUE;
  948.               }
  949.             else if (gList[gMap[groupIDs[gx][gy]]].libC > 1)
  950.               if (! killable(gx, gy, &gx1, &gx2))
  951.                 {
  952.                   restoreState();
  953. /*                  sClearChar(sChar, rXor); */
  954.                   return TRUE;
  955.                 }
  956.           undoTo(smark);
  957.         }
  958.     }
  959.   result = FALSE;
  960. one:
  961.   restoreState();
  962. /*  sClearChar(sChar, rXor); */
  963.   return result;
  964. } /* saveable */
  965.  
  966. /*
  967.   marks unsavable groups as dead
  968. */
  969. markDead()
  970. { /* markDead */
  971.   short i, j, gx, gy, result;
  972. #ifdef DEBUG
  973.   printf( "markDead\n" );
  974. #endif
  975.   for (i = 1; i <= maxGroupID; i++)
  976.       if (killable(gList[i].lx, gList[i].ly, &gx, &gy))
  977.         result = ! saveable(gList[i].lx, gList[i].ly, &gx, &gy);
  978.       else
  979.         result = FALSE;
  980.   for (i = 0; i <= maxPoint; i++)
  981.     for (j = 0; j <= maxPoint; j++)
  982.       if (bord[i][j] == 0)
  983.         ndbord[i][j] = 0;
  984.       else if (gList[groupIDs[i][j]].isDead)
  985.         ndbord[i][j] = 0;
  986.       else
  987.         ndbord[i][j] = bord[i][j];
  988. } /* markDead */
  989.  
  990. /*
  991.   marks groups with two eyes as live
  992. */
  993. MLspan(x, y, saw1, sawm1, size, sMark)
  994. short x, y, *saw1, *sawm1, *size, sMark;
  995.   { /* span */
  996.     if (ndbord[x][y] == 1)
  997.       *saw1 = TRUE;
  998.     else if (ndbord[x][y] == -1)
  999.       *sawm1 = TRUE;
  1000.     else if (sGroups[x][y] == 0)
  1001.       {
  1002.         sGroups[x][y] = sMark;
  1003.         *size = *size + 1;
  1004.         if (x > 0)
  1005.           MLspan(x - 1, y, saw1, sawm1, size, sMark);
  1006.         if (x < maxPoint)
  1007.           MLspan(x + 1, y, saw1, sawm1, size, sMark);
  1008.         if (y > 0)
  1009.           MLspan(x, y - 1, saw1, sawm1, size, sMark);
  1010.         if (y < maxPoint)
  1011.           MLspan(x, y + 1, saw1, sawm1, size, sMark);
  1012.       }
  1013.   } /* span */
  1014.  
  1015. short CLspan(x, y, numEyes, who)
  1016. short x, y, *numEyes, who;
  1017.     { /* span */
  1018.       markBoard[x][y] = marker;
  1019.       if (ndbord[x][y] == 0)
  1020.           {
  1021.             if ((sList[sGroups[x][y]].sm != marker) &&
  1022.                (sList[sGroups[x][y]].w == who))
  1023.               {
  1024.                 sList[sGroups[x][y]].sm = marker;
  1025.                 if (sList[sGroups[x][y]].s > 6)
  1026.                   return TRUE;
  1027.                 *numEyes = *numEyes + 1;
  1028.                 if (*numEyes > 1)
  1029.                   return TRUE;
  1030.               }  
  1031.           }
  1032.       else if (bord[x][y] == who)
  1033.         {
  1034.           if ((x > 0) &&
  1035.              (markBoard[x - 1][y] != marker))
  1036.             if (CLspan(x - 1, y, numEyes, who)) return TRUE;
  1037.           if ((x < maxPoint) &&
  1038.              (markBoard[x + 1][y] != marker))
  1039.             if (CLspan(x + 1, y, numEyes, who)) return TRUE;
  1040.           if ((y > 0) &&
  1041.              (markBoard[x][y - 1] != marker))
  1042.             if (CLspan(x, y - 1, numEyes, who)) return TRUE;
  1043.           if ((y < maxPoint) &&
  1044.              (markBoard[x][y + 1] != marker))
  1045.             if (CLspan(x, y + 1, numEyes, who)) return TRUE;
  1046.         }
  1047.     return FALSE;
  1048.     } /* span */
  1049.  
  1050. short checkLive(x, y)
  1051. short x, y;
  1052.   { /* checkLive */
  1053.     short numEyes, who;
  1054. #ifdef DEBUG
  1055.   printf( "checkLive\n" );
  1056. #endif
  1057.     numEyes = 0;
  1058.     who = bord[x][y];
  1059.     marker = marker + 1;
  1060.     return CLspan(x, y, &numEyes, who);
  1061.   } /* checkLive */
  1062.  
  1063. markLive()
  1064. { /* markLive */
  1065.   short i, j, size, sMark = 0;
  1066.   short saw1, sawm1;
  1067. #ifdef DEBUG
  1068.   printf( "markLive\n" );
  1069. #endif
  1070.   initArray(sGroups);
  1071.   for (i = 0; i <= maxPoint; i++)
  1072.     for (j = 0; j <= maxPoint; j++)
  1073.       if ((sGroups[i][j] == 0) &&
  1074.          (ndbord[i][j] == 0))
  1075.         {
  1076.           size = 0;
  1077.           sMark = sMark + 1;
  1078.           sawm1 = FALSE;
  1079.           saw1 = FALSE;
  1080.           MLspan(i, j, &saw1, &sawm1, &size, sMark);
  1081.           sList[sMark].s = size;
  1082.           sList[sMark].sm = 0;
  1083.           if (sawm1)
  1084.             if (saw1)
  1085.               sList[sMark].w = 0;
  1086.             else
  1087.               sList[sMark].w = -1;
  1088.           else if (saw1)
  1089.             sList[sMark].w = 1;
  1090.           else
  1091.             sList[sMark].w = 0;
  1092.         }
  1093.   for (i = 1; i <= maxGroupID; i++)
  1094.       if (! gList[i].isDead)
  1095.         gList[i].isLive = checkLive(gList[i].lx, gList[i].ly);
  1096. } /* markLive */
  1097.  
  1098. /*
  1099.   generates the connection map and the protected point map.
  1100. */
  1101. genConnects()
  1102. { /* genConnects */
  1103.   short x, y, numStones;
  1104. #ifdef DEBUG
  1105.   printf( "genConnects\n" );
  1106. #endif
  1107.   for (x = 0; x <= maxPoint; x++)
  1108.     for (y = 0; y <= maxPoint; y++)
  1109.       {
  1110.         connectMap[x][y] = 0;
  1111.         protPoints[x][y] = 0;
  1112.       }
  1113.   for (x = 0; x <= maxPoint; x++)
  1114.     for (y = 0; y <= maxPoint; y++)
  1115.       if (bord[x][y] == 1)   /* map connections to this stone */
  1116.         {
  1117.           if (x > 0)        /* direct connection */
  1118.             connectMap[x - 1][y] += 1;
  1119.           if (x < maxPoint)
  1120.             connectMap[x + 1][y] += 1;
  1121.           if (y > 0)
  1122.             connectMap[x][y - 1] += 1;
  1123.           if (y < maxPoint)
  1124.             connectMap[x][y + 1] += 1;
  1125.           if ((x > 0) && (y > 0) &&   /* diagonal connection */
  1126.              (bord[x - 1][y] == 0) && (bord[x][y - 1] == 0))
  1127.             connectMap[x - 1][y - 1] += 1;
  1128.           if ((x < maxPoint) && (y > 0) &&
  1129.              (bord[x + 1][y] == 0) && (bord[x][y - 1] == 0))
  1130.             connectMap[x + 1][y - 1] += 1;
  1131.           if ((x < maxPoint) && (y < maxPoint) &&
  1132.              (bord[x + 1][y] == 0) && (bord[x][y + 1] == 0))
  1133.             connectMap[x + 1][y + 1] += 1;
  1134.           if ((x > 0) && (y < maxPoint) &&
  1135.              (bord[x - 1][y] == 0) && (bord[x][y + 1] == 0))
  1136.             connectMap[x - 1][y + 1] += 1;
  1137.           if ((x > 1) && (claim[x - 1][y] > 3))   /* one point jump */
  1138.             connectMap[x - 2][y] += 1;
  1139.           if ((x < (maxPoint - 1)) && (claim[x + 1][y] > 3))
  1140.             connectMap[x + 2][y] += 1;
  1141.           if ((y > 1) && (claim[x][y - 1] > 3))
  1142.             connectMap[x][y - 2] += 1;
  1143.           if ((y < (maxPoint - 1)) && (claim[x][y + 1] > 3))
  1144.             connectMap[x][y + 2] += 1;
  1145.           if ((x > 1) && (y > 0) &&        /* knight's move */
  1146.              (claim[x - 1][y] > 3) && (claim[x - 1][y - 1] > 3))
  1147.             connectMap[x - 2][y - 1] += 1;
  1148.           if ((x > 0) && (y > 1) &&
  1149.              (claim[x][y - 1] > 3) && (claim[x - 1][y - 1] > 3))
  1150.             connectMap[x - 1][y - 2] += 1;
  1151.           if ((x < (maxPoint - 1)) && (y > 0) &&
  1152.              (claim[x + 1][y] > 3) && (claim[x + 1][y - 1] > 3))
  1153.             connectMap[x + 2][y - 1] += 1;
  1154.           if ((x < maxPoint) && (y > 1) &&
  1155.              (claim[x][y - 1] > 3) && (claim[x + 1][y - 1] > 3))
  1156.             connectMap[x + 1][y - 2] += 1;
  1157.           if ((x > 1) && (y < maxPoint) &&
  1158.              (claim[x - 1][y] > 3) && (claim[x - 1][y + 1] > 3))
  1159.             connectMap[x - 2][y + 1] += 1;
  1160.           if ((x > 0) && (y < (maxPoint - 1)) &&
  1161.              (claim[x][y + 1] > 3) && (claim[x - 1][y + 1] > 3))
  1162.             connectMap[x - 1][y + 2] += 1;
  1163.           if ((x < (maxPoint - 1)) && (y < maxPoint) &&
  1164.              (claim[x + 1][y] > 3) && (claim[x + 1][y + 1] > 3))
  1165.             connectMap[x + 2][y + 1] += 1;
  1166.           if ((x < maxPoint) && (y < (maxPoint - 1)) &&
  1167.              (claim[x][y + 1] > 3) && (claim[x + 1][y + 1] > 3))
  1168.             connectMap[x + 1][y + 2] += 1;
  1169.         }
  1170.       else if (bord[x][y] == 0) /* see if protected point */
  1171.         {
  1172.           numStones = 0;
  1173.           if (x == 0)
  1174.             numStones = numStones + 1;
  1175.           if (y == 0)
  1176.             numStones = numStones + 1;
  1177.           if (x == maxPoint)
  1178.             numStones = numStones + 1;
  1179.           if (y == maxPoint)
  1180.             numStones = numStones + 1;
  1181.           if ((x > 0) && (bord[x - 1][y] == 1))
  1182.             numStones = numStones + 1;
  1183.           if ((y > 0) && (bord[x][y - 1] == 1))
  1184.             numStones = numStones + 1;
  1185.           if ((x < maxPoint) && (bord[x + 1][y] == 1))
  1186.             numStones = numStones + 1;
  1187.           if ((y < maxPoint) && (bord[x][y + 1] == 1))
  1188.             numStones = numStones + 1;
  1189.           if (numStones == 4)
  1190.             protPoints[x][y] = 1;
  1191.           else if (numStones == 3)
  1192.             {
  1193.               if ((x > 0) &&
  1194.                  ((bord[x - 1][y] == 0) ||
  1195.                   ((bord[x - 1][y] == -1) &&
  1196.                    (gList[groupIDs[x - 1][y]].libC == 1))))
  1197.                  protPoints[x][y] = 1;
  1198.               else if ((x < maxPoint) &&
  1199.                       ((bord[x + 1][y] == 0) ||
  1200.                        ((bord[x + 1][y] == -1) &&
  1201.                         (gList[groupIDs[x + 1][y]].libC == 1))))
  1202.                  protPoints[x][y] = 1;
  1203.               else if ((y > 0) &&
  1204.                       ((bord[x][y - 1] == 0) ||
  1205.                        ((bord[x][y - 1] == -1) &&
  1206.                         (gList[groupIDs[x][y - 1]].libC == 1))))
  1207.                  protPoints[x][y] = 1;
  1208.               else if ((y < maxPoint) &&
  1209.                       ((bord[x][y + 1] == 0) ||
  1210.                        ((bord[x][y + 1] == -1) &&
  1211.                         (gList[groupIDs[x][y + 1]].libC == 1))))
  1212.                  protPoints[x][y] = 1;
  1213.             }
  1214.         } 
  1215.   for (x = 0; x <= maxPoint; x++)
  1216.     for (y = 0; y <= maxPoint; y++)
  1217.       if (bord[x][y] != 0)
  1218.         {
  1219.           connectMap[x][y] = 0;
  1220.           protPoints[x][y] = 0;
  1221.         }
  1222. } /* genConnects */
  1223.  
  1224. /*
  1225.   generates the whole state of the game.
  1226. */
  1227. genState()
  1228. { /* genState */
  1229. #ifdef DEBUG
  1230.   printf( "genState\n" );
  1231. #endif
  1232.   inGenState = TRUE;
  1233.   respreicen();
  1234.   markDead();
  1235.   markLive();
  1236.   spread();
  1237.   genConnects();
  1238. #ifdef DEBUG
  1239. /*  printBoard( claim, "claim" ); */
  1240. /*  printBoard( bord, "bord" ); */
  1241. /*  printBoard( ndbord, "ndbord" );
  1242.   printBoard( sGroups, "sGroups" );
  1243.   printBoard( groupIDs, "groupIDs" );
  1244.   printBoard( connectMap, "connectMap" );
  1245.   printBoard( protPoints, "protPoints" ); */
  1246. #endif
  1247.   inGenState = FALSE;
  1248. } /* genState */
  1249.  
  1250. /*
  1251.   generates a value for the [x, y] location that appears to get larger
  1252.   for points that are saddle points in the influence graph (klein)
  1253. */
  1254. short tencen(x, y)
  1255. short x, y;
  1256. { /* tencen */
  1257.   short a, b, c, d, w, z;
  1258. #ifdef DEBUG
  1259.   printf( "tencen\n" );
  1260. #endif
  1261.   if (claim[x][y] > -1)  /* if (he does not influence this area, return 50 */
  1262.     {
  1263.       return 50;
  1264.     }
  1265.   w = claim[x][y]; /* w <= -1 */
  1266.   a = iNil;
  1267.   if (x > 0)
  1268.     if (claim[x - 1][y] > -1)  /* if (neighbor is not influenced by him */
  1269.       a = claim[x - 1][y] - w;   /* score is sum of his influence on central */
  1270.   b = iNil;                      /*  point and my influence on this neighbor */
  1271.   if (y > 0)
  1272.     if (claim[x][y - 1] > -1)
  1273.       b = claim[x][y - 1] - w;
  1274.   c = iNil;
  1275.   if (x < maxPoint)
  1276.     if (claim[x + 1][y] > -1)
  1277.       c = claim[x + 1][y] - w;
  1278.   d = iNil;
  1279.   if (y < maxPoint)
  1280.     if (claim[x][y + 1] > -1)
  1281.       d = claim[x][y + 1] - w;
  1282.   z = a;             /* z = max(a, b, c, d) */
  1283.   if (z != iNil)
  1284.     {
  1285.       if ((b != iNil) &&
  1286.          (b > z))
  1287.         z = b;
  1288.     }
  1289.   else
  1290.     z = b; 
  1291.   if (z != iNil)
  1292.     {
  1293.       if ((c != iNil) &&
  1294.          (c > z))
  1295.         z = c;
  1296.     }
  1297.   else
  1298.     z = c; 
  1299.   if (z != iNil)
  1300.     {
  1301.       if ((d != iNil) &&
  1302.          (d > z))
  1303.         z = d;
  1304.     }
  1305.   else
  1306.     z = d; 
  1307.   if ((z != iNil) &&
  1308.      ((x == 0) ||
  1309.       (y == 0) ||
  1310.       (x == maxPoint) ||
  1311.       (y == maxPoint)))
  1312.     z = z * 2;     /* double z if (on the edge of the board ?? */
  1313.   if (z != iNil)
  1314.     return z;
  1315.   else
  1316.     return 50;
  1317. } /* tencen */
  1318.  
  1319. initGPUtils()
  1320. { /* initGPUtils */
  1321. #ifdef DEBUG
  1322.   printf( "initGPUtils\n" );
  1323. #endif
  1324.   initArray(markBoard);
  1325.   initState();
  1326.   marker = 0;
  1327.   playMark = 0;
  1328.       gList[0].isLive = FALSE;
  1329.       gList[0].isDead = FALSE;
  1330.       gList[0].libC = 0;
  1331.       gList[0].size = 0;
  1332.       gList[0].numEyes = 0;
  1333.       gList[0].lx = -1;
  1334.       gList[0].ly = -1;
  1335.   gMap[0] = 0;
  1336.   dbStop = FALSE;
  1337.   inGenState = FALSE;
  1338. } /* initGPUtils */
  1339.  
  1340.